﻿using Microsoft.EntityFrameworkCore;

namespace Quickly.Certs.EntityFrameworkCore
{
    public class AlibabaCloudDomainRecordRepository : IAlibabaCloudDomainRecordRepository
    {
        protected virtual CertsContext db { get; set; }

        public AlibabaCloudDomainRecordRepository(CertsContext certsContext)
        {
            db = certsContext;
        }

        private async Task<AlibabaDomainRecord?> _getRecordAsync(string domainName, string type, string recordId, CancellationToken cancellationToken)
        {
            var query = db.AlibabaDomainRecords
                .Where(x => x.RecordId == recordId && x.Domain == domainName && x.Type == type);

            var record = await query.FirstOrDefaultAsync(cancellationToken);

            return record;
        }

        public async Task<string?> GetRecordIdAsync(string domainName, string type, CancellationToken ct)
        {
            var query = db.AlibabaDomainRecords
                .AsNoTracking()
                .Where(x => x.Domain == domainName && x.Type == type && x.Deleted == false)
                .Select(x => x.RecordId);

            var recordId = await query.FirstOrDefaultAsync(ct);

            return recordId;
        }

        public async Task CreateOrUpdateAsync(string domainName, string type, string value, string recordId, CancellationToken cancellationToken)
        {
            var record = await _getRecordAsync(domainName, type, recordId, cancellationToken);

            if (record == null)
            {
                record = new AlibabaDomainRecord()
                {
                    Domain = domainName,
                    Type = type,
                    RecordId = recordId,
                    Value = value,
                    Deleted = false,
                    Created = DateTimeOffset.UtcNow,
                    LastModified = DateTimeOffset.UtcNow,
                };

                this.db.Add(record);
            }
            else
            {
                record.Value = value;
                record.Deleted = false;
                record.LastModified = DateTimeOffset.UtcNow;
            }


            await this.db.SaveChangesAsync(cancellationToken);
        }

        public async Task DeleteDomainRecordAsync(string domainName, string type, string recordId, CancellationToken ct)
        {
            var record = await _getRecordAsync(domainName, type, recordId, ct);

            if (record == null) { return; }

            record.Deleted = true;
            record.LastModified = DateTimeOffset.UtcNow;

            await this.db.SaveChangesAsync(ct);
        }
    }
}
